package structures;

import java.util.Objects;
/*
 *
 *
 */

/**
 * @param <T>
 */
public class LinkedList<T> {

    private LinkedNode head;
    private LinkedNode tail;
    private int size = 0;

    static class LinkedNode<T> {
        private T data;
        private String name;
        LinkedNode<T> next;

        LinkedNode(T data, LinkedNode<T> next) {
            this.data = data;
            this.next = next;
        }
        LinkedNode(T data) {
            this.data = data;
        }
        LinkedNode(T data,String name) {
            this.data = data;
            this.name = name;
        }
        @Override
        public String toString() {
            return "{data=" + data + ",name="+name+"}";
        }
    }

    public LinkedList() {

    }

    public LinkedList(T first) {
        add(first);
    }

    public LinkedList<T> add(T t) {
        LinkedNode<T> node = new LinkedNode<>(t,(LinkedNode<T>) null);
        if (head == null) {
            head = node;
            tail = node;
        }
        tail.next = node;
        tail = node;
        size++;
        return this;
    }

    public LinkedList<T> remove(T t) {
        LinkedNode cur = head;
        LinkedNode pre = null;
        while (cur != null) {
            if (Objects.equals(cur.data, t)) {
                if (pre == null) {
                    head = cur.next;
                } else {
                    pre.next = cur.next;
                    if (pre.next == null) {
                        tail = pre;
                    }
                }
                size--;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return this;
    }

    public void clear() {
        LinkedNode cur = head;
        while (cur != null) {
            LinkedNode tmp = cur;
            cur = cur.next;
            tmp.next = null;
        }
        head = null;
        tail = null;
        size = 0;

    }

    @Override
    public String toString() {
        LinkedNode cur = head;
        StringBuilder string = new StringBuilder("[");
        while (cur != null) {
            string.append(cur.data).append("->");
            cur = cur.next;
        }
        string.append("]");
        int len = string.length();
        return len == 2 ? "[]" : string.delete(len - 3, len - 1).toString();
    }

    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(1).add(1).add(3).add(1).add(2).add(9).add(2).add(3);
        linkedList.remove(1);
        System.out.println(linkedList);
        System.out.println(linkedList.head);
        System.out.println(linkedList.tail);
        System.out.println(linkedList.size);
        linkedList.clear();
        System.out.println(linkedList);
    }

}
